<h1>Pointcut expressions</h1>

<p>
    We've already seen one pointcut expression with our previous example:
    <code>method(Foo->doSomeStuff())</code>. The pointcut expression configures
    the filter which is used to match against join points: it is comparable to
    an <i>if</i> condition in <b>PHP</b>.
</p>

<h2>Pointcut designator</h2>

<p>
    A pointcut expression always consists of two parts: the poincut designator
    and its parameter. <b>Aspect PHP</b> supports the following designators:
</p>

<ul>
    <li>
        The <strong>method()</strong> designator
    </li>
    <li>
        The <strong>class()</strong> designator
    </li>
    <li>
        The <strong>filter()</strong> designator
    </li>
</ul>

<h3>The method() designator</h3>

<p>
    The <i>method()</i> designator matches on the execution of methods with the
    given name. The parameter specifies the class and method name, regular
    expressions can be used for more flexibility. Here's how it works:
</p>

<div class="code">
    <code>
        method(className->methodName())<br />
    </code>
</div>

<h4>Examples:</h4>

<div class="code">
    <code>
        <small>Matches all the methods on Foo:</small><br />
        method(Foo->.*())<br />
    </code>
</div>
<br />
<div class="code">
    <code>
        <small>Matches all the doSomething methods:</small><br />
        method(.*->do.*())<br />
    </code>
</div>

<p>
    You might also want to use runtime evaluations:
</p>

<div class="code">
    <code>
        <small>Matches only if the $fooParam parameter equals 'AOP' and the $otherParam parameter is greater than 6:</small><br />
        method(Foo->doSomeStuff(fooParam == "AOP", otherParam > 6))<br />
    </code>
</div>

<p class="notice">
    The supported symbols for runtime evaluations are:
    <code>==</code>, <code>!=</code>, <code>&lt;</code>, <code>&lt;=</code>,
    <code>></code>, <code>>=</code>.
</p>

<p>
    If you want to access to the property of an object given as a parameter to
    the method, just use this notation:
</p>

<div class="code">
    <code>
        <small>Matches only if $myObject->getFooParam() equals 'AOP':</small><br />
        method(Foo->doSomeStuff(myObject.fooParam == "AOP"))<br />
    </code>
</div>

<p class="notice">
    <b>Aspect PHP</b> use the convention of the camelized getters for retrieving
    the parameter value: <code>$myObject->getFooParam()</code>. If the
    <code>getFooParam()</code> method isn't found, the library will call
    directly for the attribute <code>$myObject->fooParam</code>.
</p>

<h3>The class() designator</h3>

<p>
    The <i>class()</i> designator matches on the execution of classes with the
    given name just like this:
</p>

<div class="code">
    <code>
        class(className)<br />
    </code>
</div>

<h4>Example:</h4>

<div class="code">
    <code>
        <small>Matches all the methods from class names beginning with 'Fo':</small><br />
        class(Fo.*)<br />
    </code>
</div>

<p class="notice">
    You can also negate these expressions by adding a <code>!</code> in front of
    the designator. Notice that the negation also influences the runtime
    evaluation part of the expression:
</p>

<div class="code">
    <code>
        <small>Matches all the methods from class which names do not begin with 'Fo':</small><br />
        !class(Fo.*)<br />
    </code>
</div>
<br />
<div class="code">
    <code>
        <small>Matches only if $myObject->getFooParam() isn't 'AOP' and method isn't doSomeStuff() from the Foo class:</small><br />
        !method(Foo->doSomeStuff(myObject.fooParam == 'AOP'))<br />
    </code>
</div>

<h3>The filter() designator</h3>

<p>
    <b>Aspect PHP</b> implements simple yet powerful pointcut expressions but
    you might have some more specific needs. If so, this is the place where
    you can learn how to build your own pointcut filters and match expressions
    the way you want.
</p>

<p class="notice">
    If you don't want to go any further in the details, you can safely skip this
    part and go to the next section about advices.
</p>

<p>
    The <i>filter()</i> designator allows you to implement your own logic for
    matching pointcuts. Just create a new class which extends the abstract class
    <i>aspectPointcutFilter</i>:
</p>

<div class="code">
    <code>
        <small>myPointcut.class.php</small><br />
        class myPointcut extends aspectPointcutFilter {<br />
        <br />
        &nbsp;&nbsp;&nbsp;&nbsp;public function matches(aspectJoinpoint $joinpoint) {<br />
        <br />
        &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if ($joinpoint->getClassName() == 'Foo'<br />
        &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&& $joinpoint->getMethodName() == 'doSomeStuff') {<br />
        &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return true;<br />
        &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;} else {<br />
        &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return false;<br />
        &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
        &nbsp;&nbsp;&nbsp;&nbsp;}<br />
        <br />
        }<br />
    </code>
</div>

<p class="notice">
    The possibilities given by the <i>aspectJoinpoint</i> class will be
    detailed in the next section.
</p>

<p>
    Now let's change our aspect class:
</p>

<div class="code">
    <code>
        <small>FooAspect.class.php</small><br />
        /**<br />
        &nbsp;* My foo aspect!<br />
        &nbsp;*<br />
        &nbsp;* @aspect<br />
        &nbsp;*/<br />
        class FooAspect {<br />
        <br />
        &nbsp;&nbsp;&nbsp;&nbsp;/**<br />
        &nbsp;&nbsp;&nbsp;&nbsp; * @before filter(myPointcut)<br />
        &nbsp;&nbsp;&nbsp;&nbsp; */<br />
        &nbsp;&nbsp;&nbsp;&nbsp;public function myBeforeAdvice() {<br />
        <br />
        &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;echo "I've been called before!\n";<br />
        &nbsp;&nbsp;&nbsp;&nbsp;}<br />
        <br />
        }<br />
    </code>
</div>

<p>
    We just want to add the new dependency to our program before running it:
</p>

<div class="code">
    <code>
        require_once dirname(__FILE__) . '/path/to/lib/aspectAutoloader.php';<br />
        aspectAutoloader::register();<br />
        <br />
        require_once dirname(__FILE__) . '/Foo.class.php';<br />
        require_once dirname(__FILE__) . '/FooAspect.class.php';<br />
        require_once dirname(__FILE__) . '/myPointcut.class.php';<br />
        <br />
        $aspectContainer = new aspectContainerBuilder('FooAspect');<br />
        <br />
        $foo = new aspectProxy(new Foo());<br />
        $foo->doSomeStuff('AOP');<br />
    </code>
</div>

<p>
    The execution of our program still calls for our advice:
</p>

<div class="code">
    <code>
        I've been called before!<br />
        I'm dealing with AOP!<br />
    </code>
</div>

<h4>Example: The within() designator:</h4>

<p>
    In this example, we're going to use the same mechanism to implement a
    <i>within()</i> designator which will match only the methods of classes that
    implement the right interface. Let's say we have the interface
    <i>FooInterface</i>:
</p>

<div class="code">
    <code>
        <small>FooInterface.class.php</small><br />
        interface FooInterface {<br />
        <br />
        }<br />
    </code>
</div>

<p class="notice">
    This interface is empty but it doesn't really matter right now ;)
</p>

<p>
    Next step, we have to build our custom pointcut that will match for our
    within criteria:
</p>

<div class="code">
    <code>
        <small>myWithinPointcut.class.php</small><br />
        class myWithinPointcut extends aspectPointcutFilter {<br />
        <br />
        &nbsp;&nbsp;&nbsp;&nbsp;protected $interfaceName;<br />
        <br />
        &nbsp;&nbsp;&nbsp;&nbsp;public function initialize($pointcutPattern) {<br />
        &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$this->interfaceName = $pointcutPattern;<br />
        <br />
        &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if (!interface_exists($this->interfaceName)) {<br />
        &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;throw new InvalidArgumentException(<br />
        &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"The given interface $this->interfaceName doesn't exist!");<br />
        &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
        &nbsp;&nbsp;&nbsp;&nbsp;}<br />
        <br />
        &nbsp;&nbsp;&nbsp;&nbsp;public function matches(aspectJoinpoint $joinpoint) {<br />
        &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$class = new ReflectionClass($joinpoint->getClassName());<br />
        <br />
        &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if (in_array($this->interfaceName, $class->getInterfaceNames())) {<br />
        &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return true;<br />
        &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;} else {<br />
        &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return false;<br />
        &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
        &nbsp;&nbsp;&nbsp;&nbsp;}<br />
        <br />
        }<br />
    </code>
</div>

<p class="notice">
    The <i>initialize()</i> method allows you to deal with the pointcut
    pattern and do some checkings.
</p>

<p>
    Ok! Don't forget to add the new files to your program:
</p>

<div class="code">
    <code>
        require_once dirname(__FILE__) . '/../lib/aspectAutoloader.php';<br />
        aspectAutoloader::register();<br />
        <br />
        require_once dirname(__FILE__) . '/aspect/FooInterface.class.php';<br />
        require_once dirname(__FILE__) . '/aspect/Foo.class.php';<br />
        require_once dirname(__FILE__) . '/aspect/FooAspect.class.php';<br />
        require_once dirname(__FILE__) . '/aspect/myWithinPointcut.class.php';<br />
        <br />
        $foo = new aspectProxy(new Foo());<br />
        $foo->doSomeStuff('AOP');<br />
    </code>
</div>

<p>
    Now we just have to change the expression on our aspect class:
</p>

<div class="code">
    <code>
        <small>FooAspect.class.php</small><br />
        /**<br />
        &nbsp;* My foo aspect!<br />
        &nbsp;*<br />
        &nbsp;* @aspect<br />
        &nbsp;*/<br />
        class FooAspect {<br />
        <br />
        &nbsp;&nbsp;&nbsp;&nbsp;/**<br />
        &nbsp;&nbsp;&nbsp;&nbsp; * @before filter(myWithinPointcut(FooInterface))<br />
        &nbsp;&nbsp;&nbsp;&nbsp; */<br />
        &nbsp;&nbsp;&nbsp;&nbsp;public function myBeforeAdvice() {<br />
        <br />
        &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;echo "I've been called before!\n";<br />
        &nbsp;&nbsp;&nbsp;&nbsp;}<br />
        <br />
        }<br />
    </code>
</div>

<p>
    The execution shows that our advice isn't called:
</p>

<div class="code">
    <code>
        I'm dealing with AOP!
    </code>
</div>

<p>
    So let's change the Foo class:
</p>

<div class="code">
    <code>
        <small>Foo.class.php</small><br />
        class Foo implements FooInterface {<br />
        <br />
        &nbsp;&nbsp;&nbsp;&nbsp;public function doSomeStuff($fooParam) {<br />
        <br />
        &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;echo "I'm dealing with $fooParam!";<br />
        &nbsp;&nbsp;&nbsp;&nbsp;}<br />
        <br />
        }<br />
    </code>
</div>

<p>
    And run the program again:
</p>

<div class="code">
    <code>
        I've been called before!<br />
        I'm dealing with AOP!<br />
    </code>
</div>

<p>
    That's all for the pointcut expressions. The next section is dedicated to a
    very important stuff in <b>AOP</b>: the advices!
</p>